<script lang="ts">
type VerifyInfo = { code: string };

// 倒计时
function countdown(value: number, callback: (value: number) => void) {
  if (value > 0) {
    value--;
    callback(value);
    setTimeout(() => countdown(value, callback), 1000);
  } else {
    callback(60);
  }
}
</script>

<script setup lang="ts">
import { ref, watch, computed } from 'vue';

import request from '@/utils/request';

import { showToast } from 'vant';
import SlideVerify from '@/components/slide-verify.vue';

let captcha: string; // 验证码

const show = ref(false);

const check = ref(false);

const seconds = ref(60);

const phone = ref('');

const code = ref('');

const countdownText = computed(() => `${seconds.value}秒后重试`);

watch(seconds, (value) => {
  if (55 === value) {
    showToast({
      message: `验证码：${captcha}`,
      duration: 3000,
    });
  }
});

/**
 * 显示
 */
const handleShow = (value: boolean) => {
  show.value = value;
};

/**
 * 验证
 */
const handleVerify = () => {
  if (phone.value === '') {
    return showToast('请输入手机号');
  }

  if (!/^1\d{10}$/.test(phone.value)) {
    return showToast('请输入正确手机号');
  }

  handleShow(true);
};

/**
 * 倒计时
 */
const handleTick = async () => {
  const result = await request<VerifyInfo>('/mock/verify/', 'POST', {
    phone: phone,
  });

  captcha = result.code;

  handleShow(false);

  countdown(seconds.value, (value) => (seconds.value = value));
};

/**
 * 校验
 */
const handleValidate = () => {
  return new Promise((resolve) => {
    if (phone.value === '') {
      return showToast('请输入手机号');
    }
    if (code.value === '') {
      return showToast('请输入验证码');
    }

    if (check.value === false) {
      return showToast('您还未同意《用户协议》和《隐私政策》');
    }

    if (code.value !== captcha) {
      return showToast('验证码错误');
    }

    resolve(true);
  });
};

/**
 * 登录
 */
const handleLogin = async () => {
  await handleValidate();
  showToast('登录成功');
};

/**
 * 选择
 */
const handleCheck = () => {
  check.value = !check.value;
};
</script>

<template>
  <div class="page">
    <div class="content">
      <div class="content__row">欢迎来到这里</div>

      <div class="content__row">
        <div class="content__item">手机验证码登录</div>
      </div>

      <div class="content__row">
        <div class="content__item">
          <img class="content__icon--phone" src="@/assets/image/87@2x.png" />
          <van-field
            v-model="phone"
            type="digit"
            maxlength="11"
            placeholder="请输入手机号"
            clearable
          />
        </div>

        <div class="content__item">
          <img class="content__icon--code" src="@/assets/image/88@2x.png" />
          <van-field
            v-model="code"
            type="digit"
            placeholder="请输入验证码"
            clearable
          >
            <template #button>
              <div
                class="content__btn--code"
                v-show="seconds === 60"
                @click="() => handleVerify()"
              >
                获取验证码
              </div>

              <div class="content__text" v-show="seconds < 60">
                {{ countdownText }}
              </div>
            </template>
          </van-field>
        </div>
      </div>

      <div class="content__row">
        <div class="content__btn--login" @click="() => handleLogin()">登录</div>
      </div>

      <div class="content__row">
        <div class="content__btn--forgot">忘记账号密码？</div>
      </div>

      <div class="content__row">
        <img
          class="content__icon--checked"
          v-show="check"
          src="@/assets/image/1@2x.png"
          @click="() => handleCheck()"
        />

        <img
          class="content__icon--unchecked"
          v-show="!check"
          @click="() => handleCheck()"
          src="@/assets/image/2@2x.png"
        />

        我已阅读并同意
        <div class="content__btn--protocol">《用户协议》</div>
        和
        <div class="content__btn--policy">《隐私政策》</div>
      </div>
    </div>

    <slide-verify
      v-model:show="show"
      @success="() => handleTick()"
      @close="() => handleShow(false)"
    ></slide-verify>
  </div>
</template>

<style lang="scss" scoped>
.page {
  position: relative;
  display: flex;
  justify-content: center;

  padding-top: 70px;
  width: 100%;
  height: 100%;
  background-color: #f4f5fb;

  font-size: 14px;
  color: #333333;
}

.content {
  position: relative;
  padding: 22px 26px;
  width: 316px;
  height: 350px;
  background-color: #fff;
  border-radius: 8px 8px 8px 8px;

  &__row:nth-child(1) {
    display: flex;
    justify-content: center;
    align-items: center;

    margin-bottom: 16px;
    font-size: 18px;
    font-weight: bold;
  }

  &__row:nth-child(2) {
    display: flex;
    justify-content: space-around;
    align-items: center;

    margin-bottom: 16px;
    font-size: 14px;
    color: #999999;
  }

  &__row:nth-child(2) &__item {
    &--active {
      position: relative;

      font-weight: 600;
      color: $primary;
    }

    &--active::after {
      content: '';
      position: absolute;
      left: 50%;
      bottom: -6px;
      transform: translateX(-50%);
      display: block;
      width: 30px;
      height: 4px;
      background: $primary;
      border-radius: 2px 2px 2px 2px;
    }
  }

  &__row:nth-child(3) {
    margin-bottom: 20px;
  }

  &__row:nth-child(3) &__item {
    display: flex;
    justify-content: center;
    align-items: center;

    padding: 8px;
    background-color: #efefef;
    border-radius: 6px 6px 6px 6px;
  }

  &__row:nth-child(3) &__item + &__item {
    margin-top: 12px;
  }

  &__row:nth-child(4) {
    margin-bottom: 12px;
  }

  &__row:nth-child(5) {
    display: flex;
    justify-content: flex-end;
    align-items: center;

    margin-bottom: 12px;
  }

  &__row:nth-child(6) {
    display: flex;
    justify-content: center;
    align-items: center;

    color: #999999;
    font-size: 10px;
  }

  &__item {
    &--account {
      position: relative;
    }
  }

  &__list {
    position: absolute;
    top: 45px;
    left: 0;
    z-index: 123;

    overflow-y: auto;
    padding: 8px 7px;
    width: 264px;
    max-height: 102px;
    background: #efefef;
    border-radius: 6px 6px 6px 6px;
  }

  &__list &__item {
    display: flex;
    justify-content: space-between;
    align-items: center;

    border-radius: 0 !important;
  }

  &__list &__item + &__item {
    margin-top: 0 !important;
    border-top: 1px solid #dcdcdc;
  }

  &__wrapper {
    flex: 1;
  }

  &__wrapper &__text + &__text {
    margin-top: 2px;
  }

  &__wrapper &__text:nth-child(1) {
    font-size: 12px;
    color: #333333;
  }

  &__wrapper &__text:nth-child(2) {
    font-size: 10px;
    color: #999999;
  }

  &__btn {
    &--code {
      color: $primary;
      font-weight: 400;
      font-size: 14px;
    }

    &--login {
      flex: 1;
      height: 38px;
      line-height: 38px;
      border-radius: 8px;
      background: linear-gradient(139deg, #fca743 0%, #ff774a 100%);

      color: #ffffff;
      text-align: center;
    }

    &--quick {
      display: flex;
      justify-items: center;
      align-items: center;
      color: #4186ff;
    }

    &--forgot {
      color: $primary;
    }

    &--protocol,
    &--policy {
      color: $primary;
    }

    &--close {
      position: absolute;
      top: 18px;
      right: 18px;

      width: 9px;
      height: 9px;
    }
  }

  &__icon {
    &--logo {
      margin-right: 8px;
      width: 19.78px;
      height: 22px;
    }

    &--account,
    &--password,
    &--phone,
    &--code {
      margin-right: 6px;
      width: 16px;
      height: 16px;
    }

    &--down {
      margin-right: 5px;
      width: 13.2px;
      height: 7.2px;
    }

    &--avatar {
      margin-right: 6px;
      width: 18px;
      height: 18px;
    }

    &--fork {
      width: 12px;
      height: 12px;
    }

    &--quick {
      margin-right: 4px;
      width: 10px;
      height: 10px;
    }

    &--checked,
    &--unchecked {
      margin-right: 4px;
      width: 12px;
      height: 12px;
    }
  }
}
</style>
